﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Media.Imaging;
using System.IO;
using FluxJpeg.Core;
using FluxJpeg.Core.Encoder;

namespace WallpaperCreatorForSamsungPhone
{
    /// <summary>
    /// http://kodierer.blogspot.com/2009/11/convert-encode-and-decode-silverlight.html
    /// </summary>
    public static class JpegUtils
    {
        /// <summary>
        /// Decodes the JPEG.
        /// </summary>
        /// <param name="sourceStream">The source stream.</param>
        /// <returns></returns>
        public static WriteableBitmap DecodeJpeg(Stream sourceStream)
        {
            // Decode JPEG from stream
            var decoder = new FluxJpeg.Core.Decoder.JpegDecoder(sourceStream);
            var jpegDecoded = decoder.Decode();
            var img = jpegDecoded.Image;
            img.ChangeColorSpace(ColorSpace.RGB);

            // Init Buffer
            int w = img.Width;
            int h = img.Height;
            var result = new WriteableBitmap(w, h);
            int[] p = result.Pixels;
            byte[][,] pixelsFromJpeg = img.Raster;

            // Copy FluxJpeg buffer into WriteableBitmap
            int i = 0;
            for (int x = 0; x < w; x++)
            {
                for (int y = 0; y < h; y++)
                {
                    p[i++] = (0xFF << 24)                    // A
                           | (pixelsFromJpeg[0][x, y] << 16) // R
                           | (pixelsFromJpeg[1][x, y] << 8)  // G
                           | pixelsFromJpeg[2][x, y];       // B
                }
            }

            return result;
        }

        /// <summary>
        /// Encodes the JPEG.
        /// </summary>
        /// <param name="bmp">The BMP.</param>
        /// <param name="destinationStream">The destination stream.</param>
        public static void EncodeJpeg(WriteableBitmap bmp, Stream destinationStream)
        {
            // Init buffer in FluxJpeg format
            int w = bmp.PixelWidth;
            int h = bmp.PixelHeight;
            int[] p = bmp.Pixels;
            byte[][,] pixelsForJpeg = new byte[3][,]; // RGB colors
            pixelsForJpeg[0] = new byte[w, h];
            pixelsForJpeg[1] = new byte[w, h];
            pixelsForJpeg[2] = new byte[w, h];

            // Copy WriteableBitmap data into buffer for FluxJpeg
            int i = 0;
            for (int y = 0; y < h; y++)
            {
                for (int x = 0; x < w; x++)
                {
                    int color = p[i++];
                    pixelsForJpeg[0][x, y] = (byte)(color >> 16); // R
                    pixelsForJpeg[1][x, y] = (byte)(color >> 8);  // G
                    pixelsForJpeg[2][x, y] = (byte)(color);       // B
                }
            }

            // Encode Image as JPEG using the FluxJpeg library
            // and write to destination stream
            ColorModel cm = new ColorModel { colorspace = ColorSpace.RGB };
            FluxJpeg.Core.Image jpegImage = new FluxJpeg.Core.Image(cm, pixelsForJpeg);
            JpegEncoder encoder = new JpegEncoder(jpegImage, 95, destinationStream);
            encoder.Encode();
        }
    }
}
